package configs

import (
	"fmt"
	"log"
	"os"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

var C *Config

// Config 定义整个配置文件的结构体
type Config struct {
	Server   ServerConfig   `mapstructure:"server"`
	Logger   LoggerConfig   `mapstructure:"logger"`
	Database DatabaseConfig `mapstructure:"database"`
	Redis    RedisConfig    `mapstructure:"redis"`
	Email    EmailConfig    `mapstructure:"email"`
	Cors     CorsConfig     `mapstructure:"cors"`
	JWT      JWTConfig      `mapstructure:"jwt"`
}

func New() *Config {
	return &Config{}
}
func (c *Config) Config() *Config {
	v := viper.New()
	// 配置 Viper
	v.SetConfigName("config") // 配置文件名，不需要扩展名
	v.SetConfigType("yaml")   // 配置文件类型
	// 添加多个配置文件路径，后面添加的路径优先级高
	v.AddConfigPath("/etc/ginx")
	v.AddConfigPath(".")
	v.AddConfigPath("manifest/config")
	v.AddConfigPath("../manifest/config")

	// 从环境变量中获取配置文件路径
	envConfigPath := os.Getenv("ginx_CONFIG_PATH")
	if envConfigPath != "" {
		// 将环境变量指定的路径添加到搜索路径，放在最后优先级最高
		v.AddConfigPath(envConfigPath)
	}

	// 读取配置文件
	if err := v.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			log.Fatalf("配置文件未找到: %v", err)
		} else {
			log.Fatalf("读取配置文件时出错: %v", err)
		}
	}

	// 监控配置文件变化
	v.WatchConfig()

	v.OnConfigChange(func(e fsnotify.Event) {
		log.Printf("配置文件发生变化: %s", e.Name)
		if err := v.Unmarshal(&c); err != nil {
			fmt.Println(err)
		}
		log.Printf("重载配置文件成功: %s", e.Name)
	})

	// 解析配置文件到结构体
	if err := v.Unmarshal(&c); err != nil {
		log.Fatalf("解析配置文件时出错: %v", err)
	}

	return c
}

func init() {
	C = New().Config()
}
